package cn.jianwoo.blog.service.biz.impl;import cn.jianwoo.blog.builder.JwBuilder;import cn.jianwoo.blog.constants.Constants;import cn.jianwoo.blog.dao.base.ArticleTagsTransDao;import cn.jianwoo.blog.dao.base.ArticleTransDao;import cn.jianwoo.blog.dao.base.BizPraiseTransDao;import cn.jianwoo.blog.dao.base.CommentTransDao;import cn.jianwoo.blog.dao.base.TagsTransDao;import cn.jianwoo.blog.dao.base.TempArticleTransDao;import cn.jianwoo.blog.dao.biz.ArticleBizDao;import cn.jianwoo.blog.entity.Article;import cn.jianwoo.blog.entity.ArticleTags;import cn.jianwoo.blog.entity.ArticleWithBLOBs;import cn.jianwoo.blog.entity.BizPraise;import cn.jianwoo.blog.entity.Comment;import cn.jianwoo.blog.entity.Menu;import cn.jianwoo.blog.entity.Tags;import cn.jianwoo.blog.entity.TempArticle;import cn.jianwoo.blog.entity.extension.ArticleExt;import cn.jianwoo.blog.entity.query.ArticleQuery;import cn.jianwoo.blog.enums.ArtRecmdTypeEnum;import cn.jianwoo.blog.enums.ArticleAccessEnum;import cn.jianwoo.blog.enums.ArticleDelStatusEnum;import cn.jianwoo.blog.enums.ArticleStatusEnum;import cn.jianwoo.blog.enums.AsyncIpEnum;import cn.jianwoo.blog.enums.BizEventOptTypeEnum;import cn.jianwoo.blog.enums.BizEventTypeEnum;import cn.jianwoo.blog.enums.MsgTypeEnum;import cn.jianwoo.blog.enums.PraiseTypeEnum;import cn.jianwoo.blog.enums.TaskTypeEnum;import cn.jianwoo.blog.enums.TempArticlePageEnum;import cn.jianwoo.blog.enums.TempArticleStatusEnum;import cn.jianwoo.blog.enums.TopPlaceEnum;import cn.jianwoo.blog.event.BizEventLogEvent;import cn.jianwoo.blog.exception.ArticleBizException;import cn.jianwoo.blog.exception.ArticleTagsBizException;import cn.jianwoo.blog.exception.BizPraiseBizException;import cn.jianwoo.blog.exception.CommentBizException;import cn.jianwoo.blog.exception.DaoException;import cn.jianwoo.blog.exception.JwBlogException;import cn.jianwoo.blog.service.base.ArticleBaseService;import cn.jianwoo.blog.service.base.AsyncAutoTaskBaseService;import cn.jianwoo.blog.service.base.MsgBaseService;import cn.jianwoo.blog.service.biz.AdminBizService;import cn.jianwoo.blog.service.biz.ArticleBizService;import cn.jianwoo.blog.service.biz.MenuBizService;import cn.jianwoo.blog.service.biz.TagsBizService;import cn.jianwoo.blog.service.biz.TempArticleBizService;import cn.jianwoo.blog.service.biz.UidGenService;import cn.jianwoo.blog.service.bo.AdminBO;import cn.jianwoo.blog.service.bo.ArticleBO;import cn.jianwoo.blog.service.bo.ArticleCategoryBO;import cn.jianwoo.blog.service.bo.MenuBO;import cn.jianwoo.blog.service.bo.MonthPublishBO;import cn.jianwoo.blog.service.bo.TagsBO;import cn.jianwoo.blog.service.bo.TempArticleBO;import cn.jianwoo.blog.service.param.ArticleParam;import cn.jianwoo.blog.task.bo.TaskDataD0020BO;import cn.jianwoo.blog.util.DateUtil;import cn.jianwoo.blog.util.JwUtil;import cn.jianwoo.blog.util.TestUtil;import cn.jianwoo.blog.util.TransactionUtils;import cn.jianwoo.blog.validation.BizValidation;import com.alibaba.fastjson.JSON;import com.alibaba.fastjson.JSONArray;import com.alibaba.fastjson.JSONObject;import com.github.pagehelper.Page;import com.github.pagehelper.PageHelper;import com.github.pagehelper.PageInfo;import lombok.extern.slf4j.Slf4j;import org.apache.commons.collections.CollectionUtils;import org.apache.commons.lang3.StringUtils;import org.apache.commons.text.StringEscapeUtils;import org.springframework.beans.BeanUtils;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.ApplicationContext;import org.springframework.security.core.context.SecurityContextHolder;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Transactional;import java.util.ArrayList;import java.util.Arrays;import java.util.Calendar;import java.util.Collections;import java.util.Date;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.stream.Collectors;@Service@Slf4jpublic class ArticleBizServiceImpl implements ArticleBizService {    @Autowired    private ArticleTransDao articleTransDao;    @Autowired    private ArticleTagsTransDao articleTagsTransDao;    @Autowired    private ArticleBizDao articleBizDao;    @Autowired    private UidGenService uidGenService;    @Autowired    private TempArticleBizService tempArticleBizService;    @Autowired    private MenuBizService menuBizService;    @Autowired    private TagsTransDao tagsTransDao;    @Autowired    private TagsBizService tagsBizService;    @Autowired    private TempArticleTransDao tempArticleTransDao;    @Autowired    private ApplicationContext applicationContext;    @Autowired    private BizPraiseTransDao bizPraiseTransDao;    @Autowired    private ArticleBaseService articleBaseService;    @Autowired    private AdminBizService adminBizService;    @Autowired    private CommentTransDao commentTransDao;    @Value("${admin.name}")    private String adminName;    @Autowired    private MsgBaseService msgBaseService;    @Autowired    private AsyncAutoTaskBaseService asyncAutoTaskBaseService;    @Autowired    private TransactionUtils transactionUtils;    @Override    @Transactional(rollbackFor = Exception.class)    public void doCreateArticle(ArticleBO articleBO) throws JwBlogException {        log.info("==========>Start insert article, title = {}", articleBO.getTitle());        String loginId = (String) SecurityContextHolder.getContext().getAuthentication().getPrincipal();        Long oid = uidGenService.getUid();        Date now = DateUtil.getNow();        articleBO.setIsComment(articleBO.getIsComment() != null && articleBO.getIsComment());        articleBO.setFlagOriginal(articleBO.getFlagOriginal() == null || articleBO.getFlagOriginal());        if (articleBO.getAccessType() == null) {            articleBO.setAccessType(ArticleAccessEnum.PUBLIC.getValue());        }        AdminBO admin = adminBizService.queryAdminInfoByLoginId(loginId);        String menu = null;        if (articleBO.getCategoryId() != null) {            menu = menuBizService.queryMenuNameById(articleBO.getCategoryId().longValue());        }        ArticleWithBLOBs article = JwBuilder.of(ArticleWithBLOBs::new)                .with(ArticleWithBLOBs::setOid, oid)                .with(ArticleWithBLOBs::setAuthor, articleBO.getAuthor())                .with(ArticleWithBLOBs::setCommentCount, 0L)                .with(ArticleWithBLOBs::setTitle, articleBO.getTitle())                .with(ArticleWithBLOBs::setCategoryId, articleBO.getCategoryId())                .with(ArticleWithBLOBs::setCategoryName, menu)                .with(ArticleWithBLOBs::setStatus, articleBO.getStatus())                .with(ArticleWithBLOBs::setIsComment, articleBO.getIsComment())                .with(ArticleWithBLOBs::setFlagOriginal, articleBO.getFlagOriginal())                .with(ArticleWithBLOBs::setOriginalUrl, articleBO.getOriginalUrl())                .with(ArticleWithBLOBs::setImgSrc, articleBO.getImgSrc())                .with(ArticleWithBLOBs::setAccessType, articleBO.getAccessType())                .with(ArticleWithBLOBs::setTopPlaceStatus, articleBO.getTopPlaceStatus())                .with(ArticleWithBLOBs::setContent, articleBO.getContent())                .with(ArticleWithBLOBs::setPraiseCount, 0L)                .with(ArticleWithBLOBs::setReadCount, 0L)                .with(ArticleWithBLOBs::setText, JwUtil.clearHtml(articleBO.getContent()))                .with(ArticleWithBLOBs::setCreateTime, now)                .with(ArticleWithBLOBs::setUpdateTime, now)                .with(ArticleWithBLOBs::setPushTime, now)                .with(ArticleWithBLOBs::setPushIp, articleBO.getPushIp())                .with(ArticleWithBLOBs::setPushRegion, admin.getLastLoginRegion())                .with(ArticleWithBLOBs::setPushBy, loginId)                .with(ArticleWithBLOBs::setModifiedTime, now)                .build();        if (ArticleAccessEnum.PASSWORD.getValue().equals(articleBO.getAccessType())) {            article.setPassword(JwUtil.encrypt(articleBO.getPassword()));        }        if (ArticleStatusEnum.RECYCLE.getValue().equals(article.getStatus())) {            article.setRemoveRecycleTime(now);        }        if (article.getFlagOriginal() && StringUtils.isNotBlank(article.getOriginalUrl())) {            article.setOriginalUrl(Constants.BLANK);        }        try {            articleTransDao.doInsertSelective(article);        } catch (DaoException e) {            log.error("ArticleBizServiceImpl.doSaveArticle exec failed, e:\n", e);            throw ArticleBizException.CREATE_FAILED_EXCEPTION.format(articleBO.getTitle()).print();        }        if (CollectionUtils.isNotEmpty(articleBO.getTagOidList())) {            Boolean flagActivity = ArticleStatusEnum.PUBLISHED.getValue().equals(article.getStatus());            Boolean flagPrivate = ArticleAccessEnum.PRIVATE.getValue().equals(article.getAccessType());            for (Integer t : articleBO.getTagOidList()) {                ArticleTags articleTags = JwBuilder.of(ArticleTags::new)                        .with(ArticleTags::setArticleOid, oid)                        .with(ArticleTags::setTagsOid, t)                        .with(ArticleTags::setArtFlagActivity, flagActivity)                        .with(ArticleTags::setArtFlagPrivate, flagPrivate)                        .with(ArticleTags::setCreateTime, now)                        .with(ArticleTags::setUpdateTime, now).build();                try {                    articleTagsTransDao.doInsertSelective(articleTags);                } catch (DaoException e) {                    log.error("ArticleBizServiceImpl.doSaveArticle exec failed, e:\n", e);                    throw ArticleTagsBizException.CREATE_FAILED_EXCEPTION.format("artOid:" + oid + ",tagsOid:" + t).print();                }            }        }        if (articleBO.getTempArtOid() != null) {            log.info(">>articleBO.getTempArtOid() {}", articleBO.getTempArtOid());            tempArticleBizService.doUpdateTempArticleStatus(articleBO.getTempArtOid(),                    TempArticleStatusEnum.RESTORE, article.getOid());        }        //执行异步任务        TaskDataD0020BO taskDataD0020BO = new TaskDataD0020BO();        taskDataD0020BO.setOid(article.getOid());        taskDataD0020BO.setIp(article.getPushIp());        taskDataD0020BO.setAsyncIpType(AsyncIpEnum.ARTICLE.name());        Long taskId = null;        try {            taskId = asyncAutoTaskBaseService.doCreateTask(TaskTypeEnum.D0020.getValue(), JSONObject.toJSONString(taskDataD0020BO));        } catch (JwBlogException e) {            log.error("\r\n>>ArticleBizServiceImpl.doCreateArticle exec failed, e\r\n", e);        }        if (taskId != null) {            transactionUtils.doTriggerTaskAfterCommit(taskId);        }        registerBizEvent(oid, article.getTitle(), article.getStatus(), null, false);        log.info("==========>Insert article successfully, title = {}", articleBO.getTitle());    }    @Override    @Transactional(rollbackFor = Exception.class)    public void doUpdateArticleInfo(ArticleBO articleBO) throws JwBlogException {        log.info("==========>Start update article info, title = {}", articleBO.getTitle());        Date now = DateUtil.getNow();        Article article = articleBaseService.queryArticleByOid(articleBO.getOid());        if (ArticleStatusEnum.RECYCLE.getValue().equals(article.getStatus())) {            throw ArticleBizException.STATUS_HAS_RECYCLE.format(article.getTitle()).print();        }        String menu = null;        if (articleBO.getCategoryId() != null) {            menu = menuBizService.queryMenuNameById(articleBO.getCategoryId().longValue());        }        ArticleWithBLOBs newArticle = new ArticleWithBLOBs();        newArticle.setOid(article.getOid());        newArticle.setAuthor(articleBO.getAuthor());        newArticle.setTitle(articleBO.getTitle());        newArticle.setModifiedTime(now);        newArticle.setCategoryId(articleBO.getCategoryId());        newArticle.setCategoryName(menu);        newArticle.setIsComment(articleBO.getIsComment() != null && articleBO.getIsComment());        newArticle.setFlagOriginal(articleBO.getFlagOriginal() == null || articleBO.getFlagOriginal());        newArticle.setTopPlaceStatus(articleBO.getTopPlaceStatus());        newArticle.setOriginalUrl(articleBO.getOriginalUrl());        if (articleBO.getImgSrc() != null) {            newArticle.setImgSrc(articleBO.getImgSrc());        }        if (ArticleAccessEnum.PASSWORD.getValue().equals(articleBO.getAccessType())) {            newArticle.setPassword(JwUtil.encrypt(articleBO.getPassword()));        }        if (ArticleAccessEnum.PUBLIC.getValue().equals(articleBO.getAccessType())) {            newArticle.setPassword(Constants.BLANK);        }        newArticle.setUpdateTime(now);        newArticle.setAccessType(articleBO.getAccessType() == null ? ArticleAccessEnum.PUBLIC.getValue() : articleBO.getAccessType());        if (ArticleStatusEnum.RECYCLE.getValue().equals(newArticle.getStatus())) {            newArticle.setRemoveRecycleTime(now);        }        if (newArticle.getFlagOriginal() && StringUtils.isNotBlank(newArticle.getOriginalUrl())) {            newArticle.setOriginalUrl(Constants.BLANK);        }        try {            articleTransDao.doUpdateByPrimaryKeySelective(newArticle);        } catch (DaoException e) {            log.error("ArticleBizServiceImpl.doUpdateArticleInfo exec failed, e:\n", e);            throw ArticleBizException.MODIFY_FAILED_EXCEPTION.format(articleBO.getOid()).print();        }        articleTagsTransDao.doDeleteByArticleOid(articleBO.getOid());        if (CollectionUtils.isNotEmpty(articleBO.getTagOidList())) {            Boolean flagActivity = ArticleStatusEnum.PUBLISHED.getValue().equals(article.getStatus());            Boolean flagPrivate = ArticleAccessEnum.PRIVATE.getValue().equals(newArticle.getAccessType());            for (Integer t : articleBO.getTagOidList()) {                ArticleTags articleTags = JwBuilder.of(ArticleTags::new)                        .with(ArticleTags::setArticleOid, articleBO.getOid())                        .with(ArticleTags::setTagsOid, t)                        .with(ArticleTags::setArtFlagActivity, flagActivity)                        .with(ArticleTags::setArtFlagPrivate, flagPrivate)                        .with(ArticleTags::setCreateTime, now)                        .with(ArticleTags::setUpdateTime, now).build();                try {                    articleTagsTransDao.doInsertSelective(articleTags);                } catch (DaoException e) {                    log.error("ArticleBizServiceImpl.doUpdateArticleInfo exec failed, e:\n", e);                    throw ArticleTagsBizException.CREATE_FAILED_EXCEPTION.format("artOid:" + articleBO.getOid() + ",tagsOid:" + t).print();                }            }        }        //更新评论的文章信息        if (!(newArticle.getTitle().equals(article.getTitle()) && newArticle.getAuthor().equals(article.getAuthor()))) {            List<Comment> comments = commentTransDao.queryCommentByArticleOid(article.getOid());            if (CollectionUtils.isNotEmpty(comments)) {                for (Comment comment : comments) {                    Comment newComment = new Comment();                    newComment.setOid(comment.getOid());                    newComment.setArticleAuthor(newArticle.getAuthor());                    comment.setArticleTitle(newArticle.getTitle());                    newComment.setUpdateTime(now);                    try {                        commentTransDao.doUpdateByPrimaryKeySelective(newComment);                    } catch (DaoException e) {                        throw CommentBizException.MODIFY_FAILED_EXCEPTION.format(comment.getOid()).print();                    }                }            }        }        registerBizEvent(article.getOid(), newArticle.getTitle(), null, article.getStatus(), false);        log.info("==========>Update article info successfully, title = {}", articleBO.getTitle());    }    @Override    @Transactional(rollbackFor = Exception.class)    public void doUpdateArticle(ArticleBO articleBO, String... prevStatus) throws JwBlogException {        log.info("==========>Start update article, title = {}", articleBO.getTitle());        Date now = DateUtil.getNow();        Article article = articleBaseService.queryArticleByOid(articleBO.getOid());        if (ArticleStatusEnum.RECYCLE.getValue().equals(article.getStatus())) {            throw ArticleBizException.STATUS_HAS_RECYCLE.format(article.getTitle()).print();        }        String status = article.getStatus();        if (null != prevStatus && prevStatus.length > 0) {            List<String> prevStatusList = Arrays.asList(prevStatus);            if (!prevStatusList.contains(status)) {                throw ArticleBizException.STATUS_NOT_CORRECT.format(article.getTitle(), ArticleStatusEnum.getDesc(prevStatus[0])).print();            }        }        String menu = null;        if (articleBO.getCategoryId() != null) {            menu = menuBizService.queryMenuNameById(articleBO.getCategoryId().longValue());        }        ArticleWithBLOBs newArticle = new ArticleWithBLOBs();        newArticle.setOid(article.getOid());        newArticle.setAuthor(articleBO.getAuthor());        newArticle.setTitle(articleBO.getTitle());        newArticle.setCategoryId(articleBO.getCategoryId());        newArticle.setCategoryName(menu);        newArticle.setIsComment(articleBO.getIsComment() != null && articleBO.getIsComment());        newArticle.setFlagOriginal(articleBO.getFlagOriginal() == null || articleBO.getFlagOriginal());        newArticle.setImgSrc(articleBO.getImgSrc());        newArticle.setOriginalUrl(articleBO.getOriginalUrl());        if (ArticleAccessEnum.PASSWORD.getValue().equals(articleBO.getAccessType())) {            newArticle.setPassword(JwUtil.encrypt(articleBO.getPassword()));        }        if (ArticleAccessEnum.PUBLIC.getValue().equals(articleBO.getAccessType())) {            newArticle.setPassword(Constants.BLANK);        }        newArticle.setUpdateTime(now);        newArticle.setModifiedTime(now);        newArticle.setAccessType(articleBO.getAccessType() == null ? ArticleAccessEnum.PUBLIC.getValue() : articleBO.getAccessType());        newArticle.setTopPlaceStatus(articleBO.getTopPlaceStatus());        newArticle.setContent(articleBO.getContent());        newArticle.setText(JwUtil.clearHtml(articleBO.getContent()));        if (StringUtils.isNotBlank(articleBO.getStatus())) {            newArticle.setStatus(articleBO.getStatus());            status = newArticle.getStatus();        }        if (ArticleStatusEnum.RECYCLE.getValue().equals(newArticle.getStatus())) {            newArticle.setRemoveRecycleTime(now);        }        if (newArticle.getFlagOriginal() && StringUtils.isNotBlank(newArticle.getOriginalUrl())) {            newArticle.setOriginalUrl(Constants.BLANK);        }        try {            articleTransDao.doUpdateByPrimaryKeySelective(newArticle);        } catch (DaoException e) {            log.error("ArticleBizServiceImpl.doUpdateArticle exec failed, e:\n", e);            throw ArticleBizException.MODIFY_FAILED_EXCEPTION.format(articleBO.getOid()).print();        }        articleTagsTransDao.doDeleteByArticleOid(articleBO.getOid());        if (CollectionUtils.isNotEmpty(articleBO.getTagOidList())) {            Boolean flagActivity = ArticleStatusEnum.PUBLISHED.getValue().equals(status);            Boolean flagPrivate = ArticleAccessEnum.PRIVATE.getValue().equals(newArticle.getAccessType());            for (Integer t : articleBO.getTagOidList()) {                ArticleTags articleTags = JwBuilder.of(ArticleTags::new)                        .with(ArticleTags::setArticleOid, articleBO.getOid())                        .with(ArticleTags::setTagsOid, t)                        .with(ArticleTags::setArtFlagActivity, flagActivity)                        .with(ArticleTags::setArtFlagPrivate, flagPrivate)                        .with(ArticleTags::setCreateTime, now)                        .with(ArticleTags::setUpdateTime, now).build();                try {                    articleTagsTransDao.doInsertSelective(articleTags);                } catch (DaoException e) {                    log.error("ArticleBizServiceImpl.doUpdateArticle exec failed, e:\n", e);                    throw ArticleTagsBizException.CREATE_FAILED_EXCEPTION.format("artOid:" + articleBO.getOid() + ", tagsOid:" + t).print();                }            }        }        if (articleBO.getTempArtOid() != null) {            tempArticleBizService.doUpdateTempArticleStatus(articleBO.getTempArtOid(),                    TempArticleStatusEnum.RESTORE, article.getOid());        }        //更新评论的文章信息        if (!(newArticle.getTitle().equals(article.getTitle()) && newArticle.getAuthor().equals(article.getAuthor()))) {            Comment newComment = new Comment();            newComment.setArticleAuthor(newArticle.getAuthor());            newComment.setArticleTitle(newArticle.getTitle());            try {                commentTransDao.doUpdateArtInfoByArtOidSelective(newComment, article.getOid());            } catch (DaoException ignore) {}        }        if (ArticleStatusEnum.RECYCLE.getValue().equals(newArticle.getStatus())) {            Comment newComment = new Comment();            newComment.setArtDelStatus(ArticleDelStatusEnum.REMOVE.getValue());            try {                commentTransDao.doUpdateArtInfoByArtOidSelective(newComment, newArticle.getOid());            } catch (DaoException ignore) {}        }        registerBizEvent(article.getOid(), newArticle.getTitle(), newArticle.getStatus(), article.getStatus(), false);        log.info("==========>Update article successfully, title = {}", articleBO.getTitle());    }    @Override    @Transactional(rollbackFor = Exception.class)    public void doRemoveToRecycle(Long oid) throws JwBlogException {        Article article = articleBaseService.queryArticleByOid(oid);        if (ArticleStatusEnum.RECYCLE.getValue().equals(article.getStatus())) {            throw ArticleBizException.STATUS_HAS_RECYCLE.format(article.getTitle()).print();        }        Date now = DateUtil.getNow();        ArticleWithBLOBs newArticle = new ArticleWithBLOBs();        newArticle.setOid(article.getOid());        newArticle.setStatus(ArticleStatusEnum.RECYCLE.getValue());        newArticle.setRemoveRecycleTime(now);        newArticle.setUpdateTime(now);        try {            articleTransDao.doUpdateByPrimaryKeySelective(newArticle);        } catch (DaoException e) {            log.error("ArticleBizServiceImpl.doRemoveToRecycle exec failed, e:\n", e);            throw ArticleBizException.MODIFY_FAILED_EXCEPTION.format(oid).print();        }        ArticleTags articleTags = JwBuilder.of(ArticleTags::new)                .with(ArticleTags::setArtFlagActivity, false)                .with(ArticleTags::setUpdateTime, now).build();        articleTagsTransDao.doUpdateByArticleOid(articleTags, newArticle.getOid());        Comment newComment = new Comment();        newComment.setArtDelStatus(ArticleDelStatusEnum.REMOVE.getValue());        try {            commentTransDao.doUpdateArtInfoByArtOidSelective(newComment, newArticle.getOid());        } catch (DaoException e) {            throw CommentBizException.MODIFY_FAILED_EXCEPTION.format("artOid = " + newArticle.getOid()).print();        }        registerBizEvent(article.getOid(), article.getTitle(), newArticle.getStatus(), article.getStatus(), true);    }    @Override    @Transactional(rollbackFor = Exception.class)    public void doDeleteArticle(Long oid) throws JwBlogException {        Article article = articleBaseService.queryArticleByOid(oid);        if (ArticleStatusEnum.DELETE.getValue().equals(article.getStatus())) {            throw ArticleBizException.HAS_DELETE_CN.format(article.getTitle()).print();        }        ArticleWithBLOBs newArticle = new ArticleWithBLOBs();        Date now = DateUtil.getNow();        try {            newArticle.setOid(article.getOid());            newArticle.setStatus(ArticleStatusEnum.DELETE.getValue());            newArticle.setDelTime(now);            newArticle.setUpdateTime(now);            articleTransDao.doUpdateByPrimaryKeySelective(newArticle);        } catch (DaoException e) {            log.error("ArticleBizServiceImpl.doDeleteArticle exec failed, e:\n", e);            throw ArticleBizException.DELETE_FAILED_EXCEPTION.format(oid).print();        }        ArticleTags articleTags = JwBuilder.of(ArticleTags::new)                .with(ArticleTags::setArtFlagActivity, false)                .with(ArticleTags::setUpdateTime, now).build();        articleTagsTransDao.doUpdateByArticleOid(articleTags, newArticle.getOid());        Comment newComment = new Comment();        newComment.setArtDelStatus(ArticleDelStatusEnum.REMOVE.getValue());        try {            commentTransDao.doUpdateArtInfoByArtOidSelective(newComment, newArticle.getOid());        } catch (DaoException e) {            throw CommentBizException.MODIFY_FAILED_EXCEPTION.format("artOid = " + newArticle.getOid()).print();        }        registerBizEvent(article.getOid(), article.getTitle(), newArticle.getStatus(), article.getStatus(), true);    }    @Override    @Transactional(rollbackFor = Exception.class)    public void doRemoveToDraft(Long oid) throws JwBlogException {        Article article = articleBaseService.queryArticleByOid(oid);        if (ArticleStatusEnum.DRAFT.getValue().equals(article.getStatus())) {            throw ArticleBizException.STATUS_HAS_DRAFT.format(article.getTitle()).print();        } else if (ArticleStatusEnum.RECYCLE.getValue().equals(article.getStatus())) {            throw ArticleBizException.STATUS_HAS_RECYCLE.format(article.getTitle()).print();        } else if (!ArticleStatusEnum.PUBLISHED.getValue().equals(article.getStatus())) {            throw ArticleBizException.STATUS_NOT_PUBLISHED_CN.format(article.getTitle()).print();        }        ArticleWithBLOBs newArticle = new ArticleWithBLOBs();        Date now = DateUtil.getNow();        try {            newArticle.setOid(article.getOid());            newArticle.setUpdateTime(now);            newArticle.setStatus(ArticleStatusEnum.DRAFT.getValue());            articleTransDao.doUpdateByPrimaryKeySelective(newArticle);        } catch (DaoException e) {            log.error("  ArticleBizServiceImpl.doRemoveToDraft exec failed, e:\n", e);            throw ArticleBizException.MODIFY_FAILED_EXCEPTION.format(oid).print();        }        ArticleTags articleTags = JwBuilder.of(ArticleTags::new)                .with(ArticleTags::setArtFlagActivity, false)                .with(ArticleTags::setUpdateTime, now).build();        articleTagsTransDao.doUpdateByArticleOid(articleTags, newArticle.getOid());        registerBizEvent(article.getOid(), article.getTitle(), newArticle.getStatus(), article.getStatus(), true);    }    @Override    @Transactional(rollbackFor = Exception.class)    public void doPublishedArticle(Long oid) throws JwBlogException {        ArticleWithBLOBs article = articleBaseService.queryArticleByOidWithBLOBs(oid);        if (ArticleStatusEnum.PUBLISHED.getValue().equals(article.getStatus())) {            throw ArticleBizException.STATUS_HAS_PUBLISHED.format(article.getTitle()).print();        } else if (ArticleStatusEnum.RECYCLE.getValue().equals(article.getStatus())) {            throw ArticleBizException.STATUS_HAS_RECYCLE.format(article.getTitle()).print();        } else if (!ArticleStatusEnum.DRAFT.getValue().equals(article.getStatus())) {            throw ArticleBizException.STATUS_NOT_DRAFT.format(article.getTitle()).print();        }        BizValidation.paramCategoryValidate(article.getCategoryId(), "categoryId", "文章类型不能为空!请编辑后发布");        BizValidation.paramValidate(JwUtil.clearHtmlWithoutMedia(article.getContent()), "articleContent", "文章内容不能为空!请编辑后发布");        if (null != article.getFlagOriginal() && !article.getFlagOriginal()) {            BizValidation.paramValidate(article.getOriginalUrl(), "originalUrl", "非原创时转载源链接不能为空!请编辑后发布");        }        ArticleWithBLOBs newArticle = new ArticleWithBLOBs();        Date now = DateUtil.getNow();        try {            newArticle.setOid(article.getOid());            newArticle.setUpdateTime(now);            newArticle.setStatus(ArticleStatusEnum.PUBLISHED.getValue());            articleTransDao.doUpdateByPrimaryKeySelective(newArticle);        } catch (DaoException e) {            log.error("ArticleBizServiceImpl.doPublishedArticle exec failed, e:\n", e);            throw ArticleBizException.MODIFY_FAILED_EXCEPTION.format(oid).print();        }        Boolean flagActivity = ArticleStatusEnum.PUBLISHED.getValue().equals(newArticle.getStatus());        ArticleTags articleTags = JwBuilder.of(ArticleTags::new)                .with(ArticleTags::setArtFlagActivity, flagActivity)                .with(ArticleTags::setUpdateTime, now).build();        articleTagsTransDao.doUpdateByArticleOid(articleTags, newArticle.getOid());        registerBizEvent(article.getOid(), article.getTitle(), newArticle.getStatus(), article.getStatus(), true);    }    @Override    public Integer countWithEffectiveArts() {        String[] status = new String[]{ArticleStatusEnum.DRAFT.getValue(), ArticleStatusEnum.PUBLISHED.getValue()};        return articleBizDao.countArtsByStatus(status);    }    @Override    public Integer countWithPublishArts() {        String[] status = new String[]{ArticleStatusEnum.PUBLISHED.getValue()};        return articleBizDao.countArtsByStatus(status);    }    @Override    public Integer countWithDraftArts() {        String[] status = new String[]{ArticleStatusEnum.DRAFT.getValue(),};        return articleBizDao.countArtsByStatus(status);    }    @Override    public List<ArticleBO> queryRecentPublishedArts(int n) {        Map<String, Object> params = new HashMap<>();        params.put("status", ArticleStatusEnum.PUBLISHED.getValue());        params.put("n", n);        List<Article> articleList = articleBizDao.queryArticleByStatusAndLimit(params);        List<ArticleBO> list = new ArrayList<>();        if (CollectionUtils.isNotEmpty(articleList)) {            articleList.forEach(o -> {                ArticleBO bo = new ArticleBO();                BeanUtils.copyProperties(o, bo);                list.add(bo);            });        }        return list;    }    @Override    public List<ArticleBO> queryRecentDraft(int n) {        Map<String, Object> params = new HashMap<>();        params.put("status", ArticleStatusEnum.DRAFT.getValue());        params.put("n", n);        List<Article> articleList = articleBizDao.queryArticleByStatusAndLimit(params);        List<ArticleBO> list = new ArrayList<>();        if (CollectionUtils.isNotEmpty(articleList)) {            articleList.forEach(o -> {                ArticleBO bo = new ArticleBO();                BeanUtils.copyProperties(o, bo);                list.add(bo);            });        }        return list;    }    @Override    public List<ArticleBO> queryRecycleBinArts() {        List<Article> articleList = articleTransDao.queryArticleByStatus(ArticleStatusEnum.RECYCLE.getValue());        List<ArticleBO> list = new ArrayList<>();        if (CollectionUtils.isNotEmpty(articleList)) {            articleList.forEach(o -> {                ArticleBO bo = new ArticleBO();                BeanUtils.copyProperties(o, bo);                list.add(bo);            });        }        return list;    }    @Override    public List<ArticleBO> queryDraftArts() {        List<Article> articleList = articleTransDao.queryArticleByStatus(ArticleStatusEnum.DRAFT.getValue());        List<ArticleBO> list = new ArrayList<>();        if (CollectionUtils.isNotEmpty(articleList)) {            articleList.forEach(o -> {                ArticleBO bo = new ArticleBO();                BeanUtils.copyProperties(o, bo);                list.add(bo);            });        }        return list;    }    @Override    @Transactional(rollbackFor = Exception.class)    public void doRestoreRecycleBinArts(Long oid) throws JwBlogException {        Article article = articleBaseService.queryArticleByOid(oid);        if (ArticleStatusEnum.DRAFT.getValue().equals(article.getStatus())) {            throw ArticleBizException.STATUS_HAS_DRAFT.format(article.getTitle()).print();        } else if (ArticleStatusEnum.PUBLISHED.getValue().equals(article.getStatus())) {            throw ArticleBizException.STATUS_HAS_PUBLISHED.format(article.getTitle()).print();        } else if (!ArticleStatusEnum.RECYCLE.getValue().equals(article.getStatus())) {            throw ArticleBizException.STATUS_NOT_RECYCLE.format(article.getTitle()).print();        }        ArticleWithBLOBs newArticle = new ArticleWithBLOBs();        try {            newArticle.setOid(article.getOid());            newArticle.setUpdateTime(DateUtil.getNow());            newArticle.setStatus(ArticleStatusEnum.DRAFT.getValue());            newArticle.setRemoveRecycleTime(null);            articleBizDao.doRestoreFromRecycle(newArticle);        } catch (DaoException e) {            log.error("ArticleBizServiceImpl.doRestoreRecycleBinArts exec failed, e:\n", e);            throw ArticleBizException.MODIFY_FAILED_EXCEPTION.format(oid).print();        }        Comment newComment = new Comment();        newComment.setArtDelStatus(ArticleDelStatusEnum.NOT_REMOVE.getValue());        try {            commentTransDao.doUpdateArtInfoByArtOidSelective(newComment, newArticle.getOid());        } catch (DaoException e) {            throw CommentBizException.MODIFY_FAILED_EXCEPTION.format("artOid = " + newArticle.getOid()).print();        }        registerBizEvent(article.getOid(), article.getTitle(), newArticle.getStatus(), article.getStatus(), true);    }    @Override    public List<ArticleBO> queryPublishedArticles() {        List<Article> articleList = articleTransDao.queryArticleByStatus(ArticleStatusEnum.PUBLISHED.getValue());        List<ArticleBO> list = new ArrayList<>();        if (CollectionUtils.isNotEmpty(articleList)) {            articleList.forEach(o -> {                ArticleBO bo = new ArticleBO();                BeanUtils.copyProperties(o, bo);                list.add(bo);            });        }        return list;    }    @Override    public List<ArticleBO> querySearchArtsByKeyword(String keyword) {        List<Article> articleList;        if (StringUtils.isBlank(keyword)) {            articleList = articleTransDao.queryArticleByStatus(ArticleStatusEnum.PUBLISHED.getValue());        } else {            articleList = articleBizDao.queryPublishedArtsByKeyword(keyword);        }        List<ArticleBO> list = new ArrayList<>();        if (CollectionUtils.isNotEmpty(articleList)) {            articleList.forEach(o -> {                ArticleBO bo = new ArticleBO();                BeanUtils.copyProperties(o, bo);                list.add(bo);            });        }        return list;    }    @Override    public List<ArticleBO> queryNewestArts(Integer limit) {        if (limit == null) {            limit = 10;        }        List<Article> articleList = articleBizDao.queryPublishedNewestArts(limit);        List<ArticleBO> list = new ArrayList<>();        if (CollectionUtils.isNotEmpty(articleList)) {            articleList.forEach(o -> {                ArticleBO bo = new ArticleBO();                BeanUtils.copyProperties(o, bo);                list.add(bo);            });        }        return list;    }    @Override    public List<ArticleBO> queryHotArts(Integer limit) {        if (limit == null) {            limit = 10;        }        List<Article> articleList = articleBizDao.queryPublishedHotArts(limit);        List<ArticleBO> list = new ArrayList<>();        if (CollectionUtils.isNotEmpty(articleList)) {            articleList.forEach(o -> {                ArticleBO bo = new ArticleBO();                BeanUtils.copyProperties(o, bo);                list.add(bo);            });        }        return list;    }    @Override    public List<ArticleBO> queryRandomArts(Integer limit) {        if (limit == null) {            limit = 10;        }        List<Article> arts = articleTransDao.queryArticleByStatusAndAccessType(Collections.singletonList(ArticleStatusEnum.PUBLISHED.getValue()),                Arrays.asList(ArticleAccessEnum.PUBLIC.getValue(), ArticleAccessEnum.PASSWORD.getValue()));        List<Article> randomArts = new ArrayList<>();        if (arts.size() >= limit) {            List<Integer> oids = new ArrayList<>();            for (int i = 0; i < limit; i++) {                int oid = TestUtil.getInstance().getRandomInt(0, arts.size());                if (oids.contains(oid)) {                    i--;                    continue;                }                oids.add(oid);            }            for (int i : oids) {                randomArts.add(arts.get(i));            }        } else {            randomArts = arts;        }        List<ArticleBO> list = new ArrayList<>();        if (CollectionUtils.isNotEmpty(randomArts)) {            randomArts.forEach(o -> {                ArticleBO bo = new ArticleBO();                BeanUtils.copyProperties(o, bo);                list.add(bo);            });        }        return list;    }    @Override    @Transactional(rollbackFor = Exception.class)    public void doAddPraise(String artOid, String ip) throws JwBlogException {        Long oid = Long.parseLong(artOid);        Article article = articleBaseService.queryArticleByOid(oid);        if (!ArticleStatusEnum.PUBLISHED.getValue().equals(article.getStatus())) {            throw ArticleBizException.STATUS_NOT_PUBLISHED_CN.format(article.getTitle()).print();        }        BizPraise bizPraise = bizPraiseTransDao.queryByBizOidAndIp(oid, ip, PraiseTypeEnum.ARTICLE.getValue());        if (null != bizPraise) {            throw BizPraiseBizException.PRAISE_ARTICLE_ALREADY.print();        }        try {            articleBizDao.doUpdateArticlePraiseCnt(oid);        } catch (DaoException e) {            log.error("ArticleBizServiceImpl.doAddPraise exec failed, e:\n", e);            throw ArticleBizException.MODIFY_FAILED_EXCEPTION.format(artOid).print();        }        BizPraise newArtPraise = JwBuilder.of(BizPraise::new)                .with(BizPraise::setBizOid, oid)                .with(BizPraise::setUserIp, ip)                .with(BizPraise::setType, PraiseTypeEnum.ARTICLE.getValue())                .with(BizPraise::setCreateTime, DateUtil.getNow())                .with(BizPraise::setUpdateTime, DateUtil.getNow()).build();        try {            bizPraiseTransDao.doInsertSelective(newArtPraise);        } catch (DaoException e) {            log.error("ArticleBizServiceImpl.doAddPraise exec failed, e:\n", e);            throw BizPraiseBizException.CREATE_FAILED_EXCEPTION.format(String.format("artOid=%s, ip=%s", artOid, ip)).print();        }        //创建消息        JSONObject jsonObject = new JSONObject();        jsonObject.put("title", article.getTitle());        jsonObject.put("ip", ip);        jsonObject.put("artOid", article.getOid());        msgBaseService.doCreateMsg(MsgTypeEnum.M10100001.getValue(), article.getPushBy(), null, jsonObject, article.getOid().toString());    }    @Override    public PageInfo<ArticleBO> queryEffectiveArticleList(ArticleParam param) {        Page page = PageHelper.startPage(param.getPageNo(), param.getPageSize());        ArticleQuery query = new ArticleQuery();        BeanUtils.copyProperties(param, query);        List<ArticleExt> articleExtList = articleBizDao.queryEffectiveArticleList(query);        List<ArticleBO> list = new ArrayList<>();        if (CollectionUtils.isNotEmpty(articleExtList)) {            articleExtList.forEach(o -> {                ArticleBO bo = new ArticleBO();                BeanUtils.copyProperties(o, bo);                list.add(bo);            });        }        PageInfo<ArticleBO> pageInfo = new PageInfo<>(list);        //总页数        pageInfo.setPages(page.getPages());        //总条数        pageInfo.setTotal(page.getTotal());        return pageInfo;    }    @Override    public PageInfo<ArticleBO> queryRecycleBinArticleList(ArticleParam param) {        Page page = PageHelper.startPage(param.getPageNo(), param.getPageSize());        ArticleQuery query = new ArticleQuery();        BeanUtils.copyProperties(param, query);        List<ArticleExt> articleExtList = articleBizDao.queryRecycleBinArticleList(query);        List<ArticleBO> list = new ArrayList<>();        if (CollectionUtils.isNotEmpty(articleExtList)) {            articleExtList.forEach(o -> {                ArticleBO bo = new ArticleBO();                BeanUtils.copyProperties(o, bo);                list.add(bo);            });        }        PageInfo<ArticleBO> pageInfo = new PageInfo<>(list);        //总页数        pageInfo.setPages(page.getPages());        //总条数        pageInfo.setTotal(page.getTotal());        return pageInfo;    }    @Override    @Transactional(rollbackFor = Exception.class)    public void doRemoveToRecycleBinList(List<Long> oidList) throws JwBlogException {        if (CollectionUtils.isNotEmpty(oidList)) {            for (Long oid : oidList) {                this.doRemoveToRecycle(oid);            }        }    }    @Override    @Transactional(rollbackFor = Exception.class)    public void doRestoreRecycleToDraftList(List<Long> oidList) throws JwBlogException {        if (CollectionUtils.isNotEmpty(oidList)) {            for (Long oid : oidList) {                try {                    this.doRestoreRecycleBinArts(oid);                } catch (JwBlogException e) {                    log.error("ArticleBizServiceImpl.doRestoreRecycleToDraftList exec failed, e:\n", e);                    throw ArticleBizException.DELETE_FAILED_EXCEPTION.format(oid).print();                }            }        }    }    @Override    @Transactional(rollbackFor = Exception.class)    public void doDeleteRecycleBinList(List<Long> oidList) throws JwBlogException {        if (CollectionUtils.isNotEmpty(oidList)) {            for (Long oid : oidList) {                try {                    this.doDeleteArticle(oid);                } catch (JwBlogException e) {                    log.error("ArticleBizServiceImpl.doDeleteRecycleBinList exec failed, e:\n", e);                    throw ArticleBizException.DELETE_FAILED_EXCEPTION.format(oid).print();                }            }        }    }    @Override    public ArticleBO queryArticleEditDetail(String artOid) throws JwBlogException {        ArticleWithBLOBs article;        ArticleBO bo = null;        Long oid = Long.parseLong(artOid);        article = articleBaseService.queryArticleByOidWithBLOBs(oid);        bo = JwBuilder.of(ArticleBO::new)                .with(ArticleBO::setOid, article.getOid())                .with(ArticleBO::setTitle, StringEscapeUtils.escapeHtml4(article.getTitle()))                .with(ArticleBO::setAuthor, StringEscapeUtils.escapeHtml4(article.getAuthor()))                .with(ArticleBO::setContent, article.getContent())                .with(ArticleBO::setCategoryId, article.getCategoryId())                .with(ArticleBO::setImgSrc, article.getImgSrc())                .with(ArticleBO::setIsComment, article.getIsComment())                .with(ArticleBO::setFlagOriginal, article.getFlagOriginal())                .with(ArticleBO::setOriginalUrl, article.getOriginalUrl())//                    .with(ArticleBO::setPassword, JwUtil.decrypt(article.getPassword()))                .with(ArticleBO::setAccessType, article.getAccessType())                .with(ArticleBO::setFlagTop, TopPlaceEnum.TOP.getValue().equals(article.getTopPlaceStatus()))                .with(ArticleBO::setStatus, article.getStatus())                .build();        if (StringUtils.isNotBlank(article.getPassword())) {            bo.setPassword(JwUtil.decrypt(article.getPassword()));        }        List<TagsBO> artTags = tagsBizService.queryTagsByArtOid(oid);        List<TagsBO> tagsList = new ArrayList<TagsBO>();        if (CollectionUtils.isNotEmpty(artTags)) {            for (TagsBO tag : artTags) {                TagsBO tagsListVO = JwBuilder.of(TagsBO::new)                        .with(TagsBO::setId, tag.getId())                        .with(TagsBO::setName, StringEscapeUtils.escapeHtml4(tag.getName())).build();                tagsList.add(tagsListVO);            }            bo.setArtTagsList(tagsList);        }        List<Tags> allTags = tagsTransDao.queryAllTags();        List<TagsBO> allTagsList = new ArrayList<TagsBO>();        if (CollectionUtils.isNotEmpty(allTags)) {            for (Tags tag : allTags) {                TagsBO tagsListVO = JwBuilder.of(TagsBO::new)                        .with(TagsBO::setId, tag.getOid())                        .with(TagsBO::setName, StringEscapeUtils.escapeHtml4(tag.getContent())).build();                allTagsList.add(tagsListVO);            }            bo.setAllTagsList(allTagsList);        }        List<MenuBO> categoryList = menuBizService.querySubMenuCategoryList();        List<ArticleCategoryBO> categoryVoList = new ArrayList<>();        if (CollectionUtils.isNotEmpty(categoryList)) {            for (MenuBO menu : categoryList) {                ArticleCategoryBO menuBO = JwBuilder.of(ArticleCategoryBO::new)                        .with(ArticleCategoryBO::setId, menu.getOid())                        .with(ArticleCategoryBO::setName, StringEscapeUtils.escapeHtml4(menu.getText())).build();                List<ArticleCategoryBO> subCategoryList = new ArrayList<>();                if (CollectionUtils.isNotEmpty(menu.getSubMenuList())){                    menu.getSubMenuList().forEach(o->{                        ArticleCategoryBO subBO = JwBuilder.of(ArticleCategoryBO::new)                                .with(ArticleCategoryBO::setId, o.getOid())                                .with(ArticleCategoryBO::setName, StringEscapeUtils.escapeHtml4(o.getText())).build();                        subCategoryList.add(subBO);                    });                    menuBO.setSubCategoryList(subCategoryList);                }                categoryVoList.add(menuBO);            }            bo.setCategoryList(categoryVoList);        }        TempArticle tempArticle = tempArticleTransDao.queryLastestTempArticle(oid, TempArticlePageEnum.EDIT.getValue());        if (null != tempArticle) {            TempArticleBO tempArticleInfoBO = JwBuilder.of(TempArticleBO::new)                    .with(TempArticleBO::setOid, tempArticle.getOid())                    .with(TempArticleBO::setTitle, StringEscapeUtils.escapeHtml4(tempArticle.getTitle()))                    .with(TempArticleBO::setAuthor, StringEscapeUtils.escapeHtml4(tempArticle.getAuthor()))                    .with(TempArticleBO::setContent, tempArticle.getContent())                    .with(TempArticleBO::setCategoryId, tempArticle.getCategoryId())                    .with(TempArticleBO::setImgSrc, tempArticle.getImgSrc())                    .with(TempArticleBO::setIsComment, tempArticle.getIsComment())                    .with(TempArticleBO::setFlagOriginal, tempArticle.getFlagOriginal())                    .with(TempArticleBO::setOriginalUrl, tempArticle.getOriginalUrl())//                        .with(TempArticleBO::setPassword, JwUtil.decrypt(tempArticle.getPassword()))                    .with(TempArticleBO::setAccessType, tempArticle.getAccessType())                    .with(TempArticleBO::setStatus, tempArticle.getStatus())                    .with(TempArticleBO::setFlagTop, TopPlaceEnum.TOP.getValue().equals(article.getTopPlaceStatus()))                    .build();            if (StringUtils.isNotBlank(article.getPassword())) {                bo.setPassword(JwUtil.decrypt(article.getPassword()));            }            if (StringUtils.isNotBlank(tempArticle.getTags())) {                JSONArray jsonArray = JSON.parseArray(tempArticle.getTags());                List<TagsBO> tempTagsList = new ArrayList<TagsBO>();                if (jsonArray != null && jsonArray.size() > 0) {                    for (int i = 0; i < jsonArray.size(); i++) {                        JSONObject o = jsonArray.getJSONObject(i);                        TagsBO tagsListVO = JwBuilder.of(TagsBO::new)                                .with(TagsBO::setId, o.getLong("id"))                                .with(TagsBO::setName, StringEscapeUtils.escapeHtml4(o.getString("name")))                                .build();                        tempTagsList.add(tagsListVO);                    }                    tempArticleInfoBO.setArtTagsList(tempTagsList);                }            }            bo.setTempArticle(tempArticleInfoBO);        }        return bo;    }    @Override    public ArticleBO queryArticleEditInfo(String artOid) throws JwBlogException {        Article article;        ArticleBO bo = null;        Long oid = Long.parseLong(artOid);        article = articleBaseService.queryArticleByOid(oid);        bo = JwBuilder.of(ArticleBO::new)                .with(ArticleBO::setOid, article.getOid())                .with(ArticleBO::setTitle, StringEscapeUtils.escapeHtml4(article.getTitle()))                .with(ArticleBO::setAuthor, StringEscapeUtils.escapeHtml4(article.getAuthor()))                .with(ArticleBO::setCategoryId, article.getCategoryId())                .with(ArticleBO::setImgSrc, article.getImgSrc())                .with(ArticleBO::setIsComment, article.getIsComment())                .with(ArticleBO::setFlagOriginal, article.getFlagOriginal())                .with(ArticleBO::setOriginalUrl, article.getOriginalUrl())//                    .with(ArticleBO::setPassword, JwUtil.decrypt(article.getPassword()))                .with(ArticleBO::setAccessType, article.getAccessType())                .with(ArticleBO::setFlagTop, TopPlaceEnum.TOP.getValue().equals(article.getTopPlaceStatus()))                .with(ArticleBO::setStatus, article.getStatus())                .build();        if (StringUtils.isNotBlank(article.getPassword())) {            bo.setPassword(JwUtil.decrypt(article.getPassword()));        }        List<TagsBO> artTags = tagsBizService.queryTagsByArtOid(oid);        List<TagsBO> tagsList = new ArrayList<TagsBO>();        if (CollectionUtils.isNotEmpty(artTags)) {            for (TagsBO tag : artTags) {                TagsBO tagsListVO = JwBuilder.of(TagsBO::new)                        .with(TagsBO::setId, tag.getId())                        .with(TagsBO::setName, StringEscapeUtils.escapeHtml4(tag.getName())).build();                tagsList.add(tagsListVO);            }            bo.setArtTagsList(tagsList);        }        List<Tags> allTags = tagsTransDao.queryAllTags();        List<TagsBO> allTagsList = new ArrayList<TagsBO>();        if (CollectionUtils.isNotEmpty(allTags)) {            for (Tags tag : allTags) {                TagsBO tagsListVO = JwBuilder.of(TagsBO::new)                        .with(TagsBO::setId, tag.getOid())                        .with(TagsBO::setName, StringEscapeUtils.escapeHtml4(tag.getContent())).build();                allTagsList.add(tagsListVO);            }            bo.setAllTagsList(allTagsList);        }        List<MenuBO> categoryList = menuBizService.querySubMenuCategoryList();        List<ArticleCategoryBO> categoryVoList = new ArrayList<>();        if (CollectionUtils.isNotEmpty(categoryList)) {            for (MenuBO menu : categoryList) {                ArticleCategoryBO menuBO = JwBuilder.of(ArticleCategoryBO::new)                        .with(ArticleCategoryBO::setId, menu.getOid())                        .with(ArticleCategoryBO::setName, StringEscapeUtils.escapeHtml4(menu.getText())).build();                List<ArticleCategoryBO> subCategoryList = new ArrayList<>();                if (CollectionUtils.isNotEmpty(menu.getSubMenuList())){                    menu.getSubMenuList().forEach(o->{                        ArticleCategoryBO subBO = JwBuilder.of(ArticleCategoryBO::new)                                .with(ArticleCategoryBO::setId, o.getOid())                                .with(ArticleCategoryBO::setName, StringEscapeUtils.escapeHtml4(o.getText())).build();                        subCategoryList.add(subBO);                    });                    menuBO.setSubCategoryList(subCategoryList);                }                categoryVoList.add(menuBO);            }            bo.setCategoryList(categoryVoList);        }        return bo;    }    @Override    public PageInfo<ArticleBO> queryMainArticleList(ArticleParam param, String currentIp) throws JwBlogException {        ArticleQuery query = new ArticleQuery();        BeanUtils.copyProperties(param, query);        query.setLimit(param.getPageSize());        query.setPage(param.getPageNo());        AdminBO admin = adminBizService.queryAdminInfoByLoginId(adminName.trim());        boolean isPrivate = currentIp.equals(admin.getLastLoginIp());        if (query.getCategory1() != null) {            List<Menu> menuList = menuBizService.querySubCategoryByParentId(query.getCategory1().longValue());            if (!CollectionUtils.isEmpty(menuList)) {                query.setCategorys(menuList.stream().map(m -> m.getOid().intValue()).collect(Collectors.toList()));            }        }        if (null != param.getPublishDate()) {            query.setPublishDateStart(DateUtil.getFirstTimeOfDay(param.getPublishDate()));            query.setPublishDateEnd(DateUtil.getLastTimeOfDay(param.getPublishDate()));        }        List<ArticleExt> articleExtList = articleBizDao.queryArticleListMain(query, isPrivate, currentIp);        List<ArticleBO> list = new ArrayList<>();        if (CollectionUtils.isNotEmpty(articleExtList)) {            for (ArticleExt articleExt : articleExtList) {                ArticleBO bo = new ArticleBO();                bo.setIsPraise(false);                if (articleExt.getPraiseOid() != null) {                    bo.setIsPraise(true);                }                BeanUtils.copyProperties(articleExt, bo, "text");                if (articleExt.getText().length() > 300) {                    bo.setText(articleExt.getText().substring(0, 300));                } else {                    bo.setText(articleExt.getText());                }                list.add(bo);            }        }        PageInfo<ArticleBO> pageInfo = new PageInfo<>(list);        //总条数        pageInfo.setTotal(articleBizDao.queryArticleListMainCount(query, isPrivate));        return pageInfo;    }    @Override    public ArticleBO queryArticleMainDetail(Long artOid, String currentIp) throws JwBlogException {        ArticleWithBLOBs article;        ArticleBO bo = null;        article = articleBaseService.queryArticleByOidWithBLOBs(artOid);        if (!ArticleStatusEnum.PUBLISHED.getValue().equals(article.getStatus())) {            throw ArticleBizException.STATUS_NOT_PUBLISHED_CN.format(article.getTitle()).print();        }        if (ArticleAccessEnum.PASSWORD.getValue().equals(article.getAccessType())) {            bo = JwBuilder.of(ArticleBO::new)                    .with(ArticleBO::setOid, article.getOid())                    .with(ArticleBO::setTitle, StringEscapeUtils.escapeHtml4(article.getTitle()))                    .with(ArticleBO::setPushTime, article.getPushTime())                    .with(ArticleBO::setCategoryId, article.getCategoryId())                    .with(ArticleBO::setCategoryName, article.getCategoryName())                    .with(ArticleBO::setIsLock, true)                    .with(ArticleBO::setContent, String.format(Constants.ARTICLE_NEED_PASSWORD, StringEscapeUtils.escapeHtml4(article.getTitle())))                    .build();            if (article.getText().length() > 300) {                bo.setText(article.getText().substring(0, 300));            } else {                bo.setText(article.getText());            }            return bo;        }        AdminBO admin = adminBizService.queryAdminInfoByLoginId(adminName.trim());        boolean isPrivate = currentIp.equals(admin.getLastLoginIp());        if (!isPrivate && ArticleAccessEnum.PRIVATE.getValue().equals(article.getAccessType())) {            throw ArticleBizException.PRIVATE_NOT_OPERATION.format(article.getTitle()).print();        }        Menu parentMenu = menuBizService.queryParentMenuBySubId(article.getCategoryId().longValue());        bo = JwBuilder.of(ArticleBO::new)                .with(ArticleBO::setOid, article.getOid())                .with(ArticleBO::setTitle, StringEscapeUtils.escapeHtml4(article.getTitle()))                .with(ArticleBO::setAuthor, StringEscapeUtils.escapeHtml4(article.getAuthor()))                .with(ArticleBO::setContent, article.getContent())                .with(ArticleBO::setPushTime, article.getPushTime())                .with(ArticleBO::setPushRegion, article.getPushRegion())                .with(ArticleBO::setModifiedTime, article.getModifiedTime())                .with(ArticleBO::setContent, article.getContent())                .with(ArticleBO::setCategoryId, article.getCategoryId())                .with(ArticleBO::setCategoryName, article.getCategoryName())                .with(ArticleBO::setImgSrc, article.getImgSrc())                .with(ArticleBO::setReadCount, article.getReadCount())                .with(ArticleBO::setCommentCount, article.getCommentCount())                .with(ArticleBO::setAccessType, article.getAccessType())                .with(ArticleBO::setPraiseCount, article.getPraiseCount())                .with(ArticleBO::setIsComment, article.getIsComment())                .with(ArticleBO::setFlagOriginal, article.getFlagOriginal())                .with(ArticleBO::setOriginalUrl, article.getOriginalUrl())                .with(ArticleBO::setIsLock, false)                .build();        if (null != parentMenu) {            bo.setParentCategory(parentMenu.getText());            bo.setParentCategoryId(parentMenu.getOid().intValue());        }        bo.setIsPraise(false);        BizPraise bizPraise = bizPraiseTransDao.queryByBizOidAndIp(article.getOid(), currentIp, PraiseTypeEnum.ARTICLE.getValue());        if (bizPraise != null) {            bo.setIsPraise(true);        }        List<TagsBO> artTags = tagsBizService.queryTagsByArtOid(artOid);        List<TagsBO> tagsList = new ArrayList<TagsBO>();        if (CollectionUtils.isNotEmpty(artTags)) {            for (TagsBO tag : artTags) {                TagsBO tagsListVO = JwBuilder.of(TagsBO::new)                        .with(TagsBO::setId, tag.getId())                        .with(TagsBO::setName, StringEscapeUtils.escapeHtml4(tag.getName())).build();                tagsList.add(tagsListVO);            }            bo.setArtTagsList(tagsList);        }        return bo;    }    @Override    public List<ArticleBO> queryRecommendArticleList(String type) {        List<ArticleBO> list = null;        if (ArtRecmdTypeEnum.HOT.getValue().equals(type)) {            return queryHotArts(10);        } else if (ArtRecmdTypeEnum.NEWEST.getValue().equals(type)) {            return queryNewestArts(10);        } else if (ArtRecmdTypeEnum.RANDOM.getValue().equals(type)) {            return queryRandomArts(10);        }        return queryHotArts(10);    }    @Override    public ArticleBO queryArticleMainDetail(String artOid, String password, String currentIp) throws JwBlogException {        ArticleWithBLOBs article;        ArticleBO bo = null;        Long oid = Long.parseLong(artOid);        article = articleBaseService.queryArticleByOidWithBLOBs(oid);        if (!ArticleStatusEnum.PUBLISHED.getValue().equals(article.getStatus())) {            throw ArticleBizException.STATUS_NOT_PUBLISHED_CN.format(article.getTitle()).print();        }        if (ArticleAccessEnum.PASSWORD.getValue().equals(article.getAccessType())                && !article.getPassword().equals(JwUtil.encrypt(password))) {            throw ArticleBizException.PASSWORD_INCORRECT_CN.format(article.getTitle()).print();        }        AdminBO admin = adminBizService.queryAdminInfoByLoginId(adminName.trim());        boolean isPrivate = currentIp.equals(admin.getLastLoginIp());        if (!isPrivate && ArticleAccessEnum.PRIVATE.getValue().equals(article.getAccessType())) {            throw ArticleBizException.PRIVATE_NOT_OPERATION.format(article.getTitle()).print();        }        Menu parentMenu = menuBizService.queryParentMenuBySubId(article.getCategoryId().longValue());        bo = JwBuilder.of(ArticleBO::new)                .with(ArticleBO::setOid, article.getOid())                .with(ArticleBO::setTitle, StringEscapeUtils.escapeHtml4(article.getTitle()))                .with(ArticleBO::setAuthor, StringEscapeUtils.escapeHtml4(article.getAuthor()))                .with(ArticleBO::setContent, article.getContent())                .with(ArticleBO::setPushTime, article.getPushTime())                .with(ArticleBO::setModifiedTime, article.getModifiedTime())                .with(ArticleBO::setCategoryId, article.getCategoryId())                .with(ArticleBO::setCategoryName, article.getCategoryName())                .with(ArticleBO::setImgSrc, article.getImgSrc())                .with(ArticleBO::setReadCount, article.getReadCount())                .with(ArticleBO::setCommentCount, article.getCommentCount())                .with(ArticleBO::setAccessType, article.getAccessType())                .with(ArticleBO::setPraiseCount, article.getPraiseCount())                .with(ArticleBO::setIsComment, article.getIsComment())                .with(ArticleBO::setFlagOriginal, article.getFlagOriginal())                .with(ArticleBO::setOriginalUrl, article.getOriginalUrl())                .build();        if (null != parentMenu) {            bo.setParentCategory(parentMenu.getText());            bo.setParentCategoryId(parentMenu.getOid().intValue());        }        bo.setIsPraise(false);        BizPraise bizPraise = bizPraiseTransDao.queryByBizOidAndIp(article.getOid(), currentIp, PraiseTypeEnum.ARTICLE.getValue());        if (bizPraise != null) {            bo.setIsPraise(true);        }        List<TagsBO> artTags = tagsBizService.queryTagsByArtOid(oid);        List<TagsBO> tagsList = new ArrayList<TagsBO>();        if (CollectionUtils.isNotEmpty(artTags)) {            for (TagsBO tag : artTags) {                TagsBO tagsListVO = JwBuilder.of(TagsBO::new)                        .with(TagsBO::setId, tag.getId())                        .with(TagsBO::setName, StringEscapeUtils.escapeHtml4(tag.getName())).build();                tagsList.add(tagsListVO);            }            bo.setArtTagsList(tagsList);        }        return bo;    }    @Override    public List<MonthPublishBO> queryMonthDatePublishList(String month, String currentIp) throws JwBlogException {        ArticleQuery query = new ArticleQuery();        query.setPublishDateStart(DateUtil.getFirstTimeOfMonth(month));        query.setPublishDateEnd(DateUtil.getLastTimeOfMonth(month));        AdminBO admin = adminBizService.queryAdminInfoByLoginId(adminName.trim());        boolean isPrivate = currentIp.equals(admin.getLastLoginIp());        List<ArticleExt> articleExtList = articleBizDao.queryMonthDatePublishList(query, isPrivate);        List<MonthPublishBO> list = new ArrayList<MonthPublishBO>();        for (ArticleExt article : articleExtList) {            Date pushDate = DateUtil.parseDate(article.getPushDateStr());            Calendar cal = Calendar.getInstance();            cal.setTime(pushDate);            MonthPublishBO bo = JwBuilder.of(MonthPublishBO::new)                    .with(MonthPublishBO::setDate, article.getPushDateStr())                    .with(MonthPublishBO::setCount, article.getCount())                    .with(MonthPublishBO::setDay, cal.get(Calendar.DATE))                    .build();            list.add(bo);        }        return list;    }    @Override    public List<ArticleBO> queryDetailRecommendArticle(Long oid) throws JwBlogException {        Article article = articleBaseService.queryArticleByOid(oid);        if (!ArticleStatusEnum.PUBLISHED.getValue().equals(article.getStatus())) {            throw ArticleBizException.STATUS_NOT_PUBLISHED_CN.format(article.getTitle()).print();        }        List<ArticleBO> list = new ArrayList<>();        List<ArticleExt> articleList = articleBizDao.queryRecommendArticleByArtOid(article.getOid());        if (CollectionUtils.isEmpty(articleList)) {            articleList = articleBizDao.queryRecommendArticleByCategoryOid(article.getCategoryId(), article.getOid());        }        if (CollectionUtils.isNotEmpty(articleList)) {            for (ArticleExt ext : articleList) {                ArticleBO bo = new ArticleBO();                bo.setOid(ext.getOid());                bo.setTitle(ext.getTitle());                bo.setAuthor(ext.getAuthor());                list.add(bo);            }        }        return list;    }    private void registerBizEvent(Long oid, String title, String newStatus, String oldStatus, boolean isOnlyStatusChange) {        BizEventLogEvent event = new BizEventLogEvent(this, SecurityContextHolder.getContext());        event.setBizEventTypeEnum(BizEventTypeEnum.ARTICLE);        event.setBizEventOptTypeEnum(BizEventOptTypeEnum.valueOfArticleStatus(newStatus, oldStatus, isOnlyStatusChange));        event.setOptEntityId(oid != null ? String.valueOf(oid) : null);        event.setDesc(title);        applicationContext.publishEvent(event);    }}